package com.alibaba.citrus.ots.sales.plan.repository;

import com.alibaba.citrus.ots.common.annotation.RepositoryInvoker;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.common.exception.RepositoryException;
import com.alibaba.citrus.ots.platform.enhance.repository.ChannelRepository;
import com.alibaba.citrus.ots.platform.enhance.repository.OrganizationRelationRepository;
import com.alibaba.citrus.ots.platform.enhance.repository.ScItemRepository;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.BatchQuerySalesPlanScItemRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.BatchUpdateScItemStatusRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanScItemPageQueryRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanScItemQueryRequest;
import com.alibaba.citrus.ots.sales.plan.model.features.SalesPlanScItemFeatures;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanScItemSDO;
import com.alibaba.cz.base.model.store.ChannelSDO;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.bosalesplanproduct.dto.SearchPlanProdecyRequest;
import com.epoch.app.bcots.bosalesplanproduct.dto.SearchPlanProdecyResponse;
import com.epoch.app.bcots.bosalesplanproduct.model.BoSalesPlanProduct;
import com.epoch.app.bcots.bosalesplanproduct.service.BoSalesPlanProductService;
import com.epoch.app.bcots.model.dto.BaselineGetOrganizationByIdsRequest;
import com.epoch.app.bcots.model.dto.CategorySDO;
import com.epoch.app.bcots.model.dto.QueryCategoryInfoByIdsRequest;
import com.epoch.app.bcots.sales_plan.salesplanscitem.dto.BatchQueryRequest;
import com.epoch.app.bcots.sales_plan.salesplanscitem.dto.BatchQueryResponse;
import com.epoch.app.bcots.sales_plan.salesplanscitem.dto.CreateSalesPlanScItemResponse;
import com.epoch.app.bcots.sales_plan.salesplanscitem.dto.LoadSalesPlanScItemRequest;
import com.epoch.app.bcots.sales_plan.salesplanscitem.dto.SalesPlanScItemLoadListRequest;
import com.epoch.app.bcots.sales_plan.salesplanscitem.dto.UpdateSalesPlanScItemResponse;
import com.epoch.app.bcots.sales_plan.salesplanscitem.model.SalesPlanScItem;
import com.epoch.app.bcots.sales_plan.salesplanscitem.service.SalesPlanScItemService;
import com.epoch.app.bcots.service.BaseDataService;
import com.epoch.app.otsplatformenhance.dto.request.IdQueryRequest;
import com.epoch.app.otsplatformenhance.enums.OrganizationRelevanceTypeEnum;
import com.epoch.app.otsplatformenhance.model.dto.ScItemSDO;
import com.epoch.app.otsplatformenhance.sdo.OrganizationRelationSDO;
import com.epoch.app.otspricecenter.dto.request.DimensionPropertyInfoRequest;
import com.epoch.app.otspricecenter.dto.request.MaterialInfoRequest;
import com.epoch.app.otspricecenter.dto.request.PlaceInfoRequest;
import com.epoch.app.otspricecenter.dto.request.PriceQueryRequest;
import com.epoch.app.otspricecenter.dto.response.ItemPriceResponse;
import com.epoch.app.otspricecenter.dto.response.PriceQueryResponse;
import com.epoch.app.otspricecenter.model.dto.BatchQueryPriceRequest;
import com.epoch.app.otspricecenter.model.dto.BatchQueryPriceResponse;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author wangyibing
 */
@Component
public class SalesPlanScItemRepositoryImpl implements SalesPlanScItemRepository {

    @Resource
    private SalesPlanScItemService salesPlanScItemService;

    @Resource
    private ScItemRepository scItemRepository;

    @Resource
    private OrganizationRelationRepository organizationRelationRepository;

    @Resource
    private ChannelRepository channelRepository;

    @Resource
    private BaseDataService baseDataService;

    private static final Integer ZERO = 0;

    @Override
    @RepositoryInvoker(printLog = true)
    public SalesPlanScItemSDO querySalesPlanScItem(SalesPlanScItemQueryRequest planQueryRequest) {
        LoadSalesPlanScItemRequest loadRequest = productPlanQueryRequestConverter(planQueryRequest);
        SalesPlanScItem salesPlanScItem = salesPlanScItemService.loadSalesPlanScItem(loadRequest);
        SalesPlanScItemSDO salesPlanScItemSDO = new SalesPlanScItemSDO();
        BeanUtils.copyProperties(salesPlanScItem, salesPlanScItemSDO);
        // 获取货品名称
        ScItemSDO scItem = scItemRepository.getScItem(salesPlanScItemSDO.getScItemId());
        if (Objects.nonNull(scItem)) {
            salesPlanScItemSDO.setScItemName(scItem.getTitle());
        }
        return salesPlanScItemSDO;
    }

    private LoadSalesPlanScItemRequest productPlanQueryRequestConverter(SalesPlanScItemQueryRequest planQueryRequest) {
        LoadSalesPlanScItemRequest loadSalesPlanScItemRequest = new LoadSalesPlanScItemRequest();
        BeanUtils.copyProperties(planQueryRequest, loadSalesPlanScItemRequest);
        return loadSalesPlanScItemRequest;
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public String createSalesPlanScItem(SalesPlanScItemSDO salesPlanScItemSDO) {
        ScItemSDO scItem = scItemRepository.getScItem(salesPlanScItemSDO.getScItemId());
        String leafCategoryId = scItem.getLeafCategoryId();
        if (StringUtils.isNotEmpty(leafCategoryId)) {
            QueryCategoryInfoByIdsRequest build = QueryCategoryInfoByIdsRequest.builder().categoryIdList(Lists.newArrayList(leafCategoryId)).build();
            Result<List<CategorySDO>> listResult = baseDataService.queryCategoryInfoByIds(build);
            if (listResult != null || listResult.isSuccess() || listResult.getResult() != null) {
                CategorySDO categorySDO = listResult.getResult().stream().findFirst().get();
                if (categorySDO.getRoot()) {
                    //该类目是根节点
                    salesPlanScItemSDO.setScItemRootCategoryId(categorySDO.getRootCategoryId());
                } else {
                    //叶子节点
                    salesPlanScItemSDO.setScItemLeafCategoryId(categorySDO.getCategoryId());
                    salesPlanScItemSDO.setScItemRootCategoryId(categorySDO.getRootCategoryId());
                }
            }
        }

        SalesPlanScItem createRequest = productPlanCreateRequestConverter(salesPlanScItemSDO);
        CreateSalesPlanScItemResponse response = salesPlanScItemService.createSalesPlanScItem(createRequest);
        return response.getLastInsertId();
    }

    private void fillInItemPrice(SalesPlanScItemSDO salesPlanScItemSDO, BatchQueryPriceResponse batchQueryPriceResponse) {
        if (Objects.isNull(batchQueryPriceResponse)) {
            return;
        }
        Result<PriceQueryResponse> priceQueryResponseResult = (Result<PriceQueryResponse>) batchQueryPriceResponse.getResult();
        if (Objects.isNull(priceQueryResponseResult)) {
            return;
        }
        PriceQueryResponse result = priceQueryResponseResult.getResult();
        if (CollectionUtils.isEmpty(result.getItemPriceResponseList())) {
            return;
        }
        ItemPriceResponse priceResponse = result.getItemPriceResponseList().stream().findFirst().get();
        //计算单价
        Long price = priceResponse.getMoneyAmout() / priceResponse.getItemCount();
        salesPlanScItemSDO.setCostInsuranceFreight(price);
    }

    //todo 构造价格批量查询参数
    private BatchQueryPriceRequest buildPriceQueryRequest(SalesPlanScItemSDO salesPlanScItemSDO) {
        DimensionPropertyInfoRequest dimensionPropertyInfoRequest = new DimensionPropertyInfoRequest();
        //价格类型
        dimensionPropertyInfoRequest.setPriceTypeId("ZP01");
        /**
         * 产品组编码
         * 货品编码
         */
        MaterialInfoRequest materialInfoRequest = new MaterialInfoRequest();
        //todo  物料编码是outId,修改
        ScItemSDO scItem = scItemRepository.getScItem(salesPlanScItemSDO.getScItemId());
        if (Objects.nonNull(scItem)) {
            String materialCode = scItem.getOuterId();
            materialInfoRequest.setMaterialCode(materialCode);
        }
        materialInfoRequest.setScItemGroupCode("11");
        dimensionPropertyInfoRequest.setMaterialInfoRequest(materialInfoRequest);

        /**
         * 销售组织编码
         * 分销渠道编码(业务渠道)
         * 销售单位编码
         */
        PlaceInfoRequest placeInfoRequest = PlaceInfoRequest.builder().build();
        //根据销售渠道获取业务渠道
        IdQueryRequest idQueryRequest = new IdQueryRequest();
        idQueryRequest.setId(salesPlanScItemSDO.getOrgSalesChannelCode());
        idQueryRequest.setType(OrganizationRelevanceTypeEnum.CHANNEL.getCode());
        PageResult<List<OrganizationRelationSDO>> organizationRelationByOrgId = organizationRelationRepository.getOrganizationRelationByOrgId(idQueryRequest);
        if (CollectionUtils.isNotEmpty(organizationRelationByOrgId.getContent())) {
            enrichOrgChannelList(organizationRelationByOrgId.getContent());
            OrganizationRelationSDO organizationRelationSDO = organizationRelationByOrgId.getContent().stream().findFirst().get();
            placeInfoRequest.setChannelCode(organizationRelationSDO.getOutCode());
        }
        //销售组织编码转换为outerCode
        BaselineGetOrganizationByIdsRequest build = BaselineGetOrganizationByIdsRequest.builder().status(1).ids(Lists.newArrayList(salesPlanScItemSDO.getOrgSalesOrganizationCode())).build();
        Object o = baseDataService.baselineGetOrganizationByIds(build);
        String salesOrgCode = convertBatchOrg(o);
        placeInfoRequest.setOrgSalesOrganizationCode(salesOrgCode);
        placeInfoRequest.setSalesUnitCode("GUA");
        dimensionPropertyInfoRequest.setPlaceInfoRequest(placeInfoRequest);
        PriceQueryRequest priceQueryRequest = new PriceQueryRequest();
        ArrayList<DimensionPropertyInfoRequest> requestArrayList = Lists.newArrayList(dimensionPropertyInfoRequest);
        priceQueryRequest.setDimensionPropertyInfoRequestList(requestArrayList);
        BatchQueryPriceRequest batchQueryPriceRequest = new BatchQueryPriceRequest();
        BeanUtils.copyProperties(priceQueryRequest, batchQueryPriceRequest);
        dimensionPropertyInfoRequest.setPriceUseDate(new Date());
        return batchQueryPriceRequest;
    }

    @Resource
    private BoSalesPlanProductService boSalesPlanProductService;

    @Override
    @RepositoryInvoker(printLog = true)
    public PageResult<List<SalesPlanScItemSDO>> pageQuerySalesPlanScItemList(SalesPlanScItemPageQueryRequest planPageQueryRequest) {
        SearchPlanProdecyRequest searchPlanProdecyRequest = new SearchPlanProdecyRequest();
        List<String> scItemIdList = planPageQueryRequest.getScItemIdList();
        if (StringUtils.isNotBlank(planPageQueryRequest.getOrgBusinessUnitCode())) {
            searchPlanProdecyRequest.setOrgBusinessUnitCodeList(Lists.newArrayList(planPageQueryRequest.getOrgBusinessUnitCode()));
        }
        if (StringUtils.isNotBlank(planPageQueryRequest.getOrgSalesOrganizationCode())) {
            searchPlanProdecyRequest.setOrgSalesOrganizationCodeList(Lists.newArrayList(planPageQueryRequest.getOrgSalesOrganizationCode()));
        }
        if (StringUtils.isNotBlank(planPageQueryRequest.getOrgSalesChannelCode())) {
            searchPlanProdecyRequest.setOrgSalesChannelCodeList(Lists.newArrayList(planPageQueryRequest.getOrgSalesChannelCode()));
        }
        if (StringUtils.isNotBlank(planPageQueryRequest.getScItemId())) {
            if (CollectionUtils.isEmpty(scItemIdList)) {
                searchPlanProdecyRequest.setScItemIdList(Lists.newArrayList(planPageQueryRequest.getScItemId()));
            }
        }
        if (CollectionUtils.isNotEmpty(scItemIdList)) {
            searchPlanProdecyRequest.setScItemIdList(scItemIdList);
            if (StringUtils.isNotBlank(planPageQueryRequest.getScItemId())) {
                if (scItemIdList.contains(planPageQueryRequest.getScItemId())) {
                    searchPlanProdecyRequest.setScItemIdList(Lists.newArrayList(planPageQueryRequest.getScItemId()));
                } else {
                    throw new RepositoryException("OTS-02-001-00-15-0010");
                }
            }
        }
        if (CollectionUtils.isNotEmpty(planPageQueryRequest.getOrgBusinessUnitCodes())) {
            searchPlanProdecyRequest.setOrgBusinessUnitCodeList(planPageQueryRequest.getOrgBusinessUnitCodes());
        }
        searchPlanProdecyRequest.setScItemName(planPageQueryRequest.getScItemName());
        searchPlanProdecyRequest.setStatus(planPageQueryRequest.getStatus());
        searchPlanProdecyRequest.setStart(planPageQueryRequest.getStart());
        searchPlanProdecyRequest.setLimit(planPageQueryRequest.getLimit());

        SearchPlanProdecyResponse planProductResponse = boSalesPlanProductService.searchPlanProdecy(searchPlanProdecyRequest);
        if (planProductResponse == null || CollectionUtils.isEmpty(planProductResponse.getResult())) {
            return PageResult.of(Lists.newArrayList(), 0);
        }

        List<BoSalesPlanProduct> boSalesPlanProducts = planProductResponse.getResult();
        List<SalesPlanScItemSDO> resultList = boSalesPlanProducts.stream().map(salesPlanScItem -> {
            SalesPlanScItemSDO salesPlanScItemSDO = new SalesPlanScItemSDO();
            BeanUtils.copyProperties(salesPlanScItem, salesPlanScItemSDO);
//            salesPlanScItemSDO.setGmt_create(salesPlanScItem.getGmtCreate());
//            salesPlanScItemSDO.setGmt_modified(salesPlanScItem.getGmtModified());
            salesPlanScItemSDO.setGmt_create(salesPlanScItem.getGmt_create());
            salesPlanScItemSDO.setGmt_modified(salesPlanScItem.getGmt_modified());
            return salesPlanScItemSDO;
        }).collect(Collectors.toList());
        return PageResult.of(resultList, planProductResponse.getTotal());
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public Integer editSalesPlanScItem(SalesPlanScItemSDO salesPlanScItemSDO) {
        ScItemSDO scItem = scItemRepository.getScItem(salesPlanScItemSDO.getScItemId());
        if (scItem == null) {
            return ZERO;
        }
        salesPlanScItemSDO.setScItemLeafCategoryId(scItem.getLeafCategoryId());
        SalesPlanScItem updateRequest = productPlanEditConverter(salesPlanScItemSDO);
        UpdateSalesPlanScItemResponse updateSalesPlanScItemResponse = salesPlanScItemService.updateSalesPlanScItem(updateRequest);
        return updateSalesPlanScItemResponse.getCount();
    }

    @Override
    public ScItemSDO queryScItemById(String scItemId) {
        return scItemRepository.getScItem(scItemId);
    }

    @Override
    public List<SalesPlanScItemSDO> batchQuerySalesPlanScItem(BatchQuerySalesPlanScItemRequest batchQuerySalesPlanScItemRequest) {
        BatchQueryRequest batchQueryRequest = new BatchQueryRequest();
        if (null != batchQuerySalesPlanScItemRequest.getScItemIds()) {
            batchQueryRequest.setScItemIds(batchQuerySalesPlanScItemRequest.getScItemIds());
        }
        if (null != batchQuerySalesPlanScItemRequest.getStatus()) {
            batchQueryRequest.setStatus(batchQuerySalesPlanScItemRequest.getStatus());
        }
        if (CollectionUtils.isNotEmpty(batchQuerySalesPlanScItemRequest.getOrgBusinessUnitCodeList())) {
            batchQueryRequest.setOrgBusinessUnitCodeList(batchQuerySalesPlanScItemRequest.getOrgBusinessUnitCodeList());
        }
        if (CollectionUtils.isNotEmpty(batchQuerySalesPlanScItemRequest.getOrgSaleOrganizationCodeList())) {
            batchQueryRequest.setOrgSaleOrganizationCodeList(batchQuerySalesPlanScItemRequest.getOrgSaleOrganizationCodeList());
        }
        if (CollectionUtils.isNotEmpty(batchQuerySalesPlanScItemRequest.getOrgSaleChannelCodeList())) {
            batchQueryRequest.setOrgSaleChannelCodeList(batchQuerySalesPlanScItemRequest.getOrgSaleChannelCodeList());
        }
        BatchQueryResponse batchQueryResponse = salesPlanScItemService.batchQuery(batchQueryRequest);
        if (CollectionUtils.isEmpty(batchQueryResponse.getResult())) {
            return Lists.newArrayList();
        }
        List<SalesPlanScItemSDO> collect = batchQueryResponse.getResult().stream().map(it -> {
            SalesPlanScItemSDO salesPlanScItemSDO = new SalesPlanScItemSDO();
            BeanUtils.copyProperties(it, salesPlanScItemSDO);
            return salesPlanScItemSDO;
        }).collect(Collectors.toList());
        return collect;
    }

    private SalesPlanScItem productPlanEditConverter(SalesPlanScItemSDO productPlanEditRequest) {
        SalesPlanScItem updateRequest = new SalesPlanScItem();
        BeanUtils.copyProperties(productPlanEditRequest, updateRequest);
        return updateRequest;
    }

    private SalesPlanScItemLoadListRequest productPlanPageQueryConverter(SalesPlanScItemPageQueryRequest planPageQueryRequest) {
        SalesPlanScItemLoadListRequest loadListRequest = new SalesPlanScItemLoadListRequest();
        BeanUtils.copyProperties(planPageQueryRequest, loadListRequest);
        return loadListRequest;
    }

    private SalesPlanScItem productPlanCreateRequestConverter(SalesPlanScItemSDO planCreateRequest) {
        SalesPlanScItem createRequest = new SalesPlanScItem();
        BeanUtils.copyProperties(planCreateRequest, createRequest);
        SalesPlanScItemFeatures salesPlanScItemFeatures = planCreateRequest.getSalesPlanScItemFeatures();
        if (!Objects.isNull(salesPlanScItemFeatures)) {
            String features = JSON.toJSONString(salesPlanScItemFeatures);
            createRequest.setFeatures(features);
        }
        return createRequest;
    }

    private String convertBatchOrg(Object obj) {
        JSONObject o = JSONObject.parseObject(JSONObject.toJSONString(obj));
        if (o != null) {
            JSONArray array = o.getJSONArray("result");
            if (array.size() > 0) {
                JSONObject j = array.getJSONObject(0).getJSONObject("organizationSDO");
                return (String) j.get("outCode");
            }
        }
        return null;
    }

    private void enrichOrgChannelList(
            List<com.epoch.app.otsplatformenhance.sdo.OrganizationRelationSDO> organizationRelList) {
        List<String> idList = organizationRelList.stream().map(sdo -> {
            return sdo.getRelevanceId();
        }).collect(Collectors.toList());

        List<ChannelSDO> channelList = channelRepository.batchQueryChannel(idList);
        Map<String, ChannelSDO> channelMap = channelList.stream().collect(Collectors.toMap(ChannelSDO::getChannelId, Function.identity(), (v1, v2) -> v1));
        organizationRelList.forEach(sdo -> {
            ChannelSDO channelSDO = channelMap.get(sdo.getRelevanceId());
            sdo.setName(channelSDO.getChannelName());
            sdo.setCode(channelSDO.getChannelCode());
            sdo.setOutCode(channelSDO.getOutCode());
        });
    }


    @Override
    public Integer batchUpdateStatus(SalesPlanScItemSDO batchUpdateScItem) {
        SalesPlanScItem salesPlanScItem = new SalesPlanScItem();
        salesPlanScItem.setId(batchUpdateScItem.getId());
        salesPlanScItem.setStatus(batchUpdateScItem.getStatus());
        UpdateSalesPlanScItemResponse response = salesPlanScItemService.updateSalesPlanScItem(salesPlanScItem);
        Integer count = response.getCount();
        return count;
    }
}
